#include "Cube.h"
#include <qgl.h>
namespace GCL { namespace MagicCube {


Cube::Cube(const Vec3 &center, Scalar length)
{
    this->center_ = center;
    this->init(center,length);
}

Cube::~Cube()
{

}

void Cube::init(const Vec3 &center, Scalar length)
{
    positions_.clear();
    //根据旋转中心设置正方体顶点坐标
    positions_.push_back(center + Vec3(-1,-1,1)  * length);
    positions_.push_back(center + Vec3(1,-1,1)   * length);
    positions_.push_back(center + Vec3(1,1,1)    * length);
    positions_.push_back(center + Vec3(-1,1,1)   * length);
    positions_.push_back(center + Vec3(-1,-1,-1) * length);
    positions_.push_back(center + Vec3(1,-1,-1)  * length);
    positions_.push_back(center + Vec3(1,1,-1)   * length);
    positions_.push_back(center + Vec3(-1,1,-1)  * length);
    //设置正方体六面的颜色
    colors_.clear();

    if(center[0]*10 <= 2.1 && center[0]*10 >= 1.9)
        colors_.push_back(Vec4(1,1,1,1));
    else
        colors_.push_back(Vec4(0,0,0,1));

    if(center[0]*10 <= -1.9 && center[0]*10 >= -2.1)
         colors_.push_back(Vec4(0,1,0,1));
    else
         colors_.push_back(Vec4(0,0,0,1));


    if(center[1]*10 <= 2.1 && center[1]*10 >= 1.9)
        colors_.push_back(Vec4(1,0,0,1));
    else
        colors_.push_back(Vec4(0,0,0,1));

    if(center[1]*10 <= -1.9 && center[1]*10 >= -2.1)
        colors_.push_back(Vec4(1,1,0,1));
    else
        colors_.push_back(Vec4(0,0,0,1));


    if(center[2]*10 <= 2.1 && center[2]*10 >= 1.9)
         colors_.push_back(Vec4(0,0,1,1));
    else
        colors_.push_back(Vec4(0,0,0,1));

    if(center[2]*10 <= -1.9 && center[2]*10 >= -2.1)
        colors_.push_back(Vec4(1,0,1,1));
    else
       colors_.push_back(Vec4(0,0,0,1));

}


//正方体进行旋转变换
void Cube::rotate(const Vec3 &axis, Scalar angle)
{
    int num=positions_.size();
    Quat quat(axis,angle);
    HomoMatrix4 matrix=quat.convertToMatrix();
    //对顶点进行旋转变换
    for(int i=0; i<num; ++i)
    {
        positions_[i]= matrix.RotateVector(positions_[i]);
    }
    //对中心进行旋转变换
    center_ = matrix.RotateVector(center_);
}

//开始对正方体上色
void Cube::render()
{

    //0，1，2，3代表第0、第一、第二、第三个顶点
    //利用四个顶点来标识一面

    renderFace(2,1,5,6,colors_[0]);
    renderFace(0,3,7,4,colors_[1]);
    renderFace(3,2,6,7,colors_[2]);
    renderFace(1,0,4,5,colors_[3]);
    renderFace(0,1,2,3,colors_[4]);
    renderFace(7,6,5,4,colors_[5]);


    /*renderFace(0,1,2,3,colors_[0]);
    renderFace(7,6,5,4,colors_[1]);
    renderFace(1,0,4,5,colors_[2]);
    renderFace(2,1,5,6,colors_[3]);
    renderFace(3,2,6,7,colors_[4]);
    renderFace(0,3,7,4,colors_[5]);
    */
}

//具体的上色函数
void Cube::renderFace(int v0, int v1, int v2, int v3, const Vec4 &color)
{
    Vec3 pv[4];
    pv[0] = positions_[v0];
    pv[1] = positions_[v1];
    pv[2] = positions_[v2];
    pv[3] = positions_[v3];

    Vec3 normal = (pv[1] - pv[0]) ^ (pv[2] - pv[0]);
    normal.Normalize();

    glColor4dv(color.data());
    glNormal3d(normal[0],normal[1],normal[2]);
    glBegin(GL_QUADS);
        for(int i=0; i < 4; i++)
        {
            glVertex3dv(pv[i].data());
        }
    glEnd();
    glColor4d(0,0,0,1);
    glBegin(GL_LINES);
    for(int i=0; i < 4; i++)
    {
       glVertex3dv(pv[i].data());
       glVertex3dv(pv[(i+1)%4].data());
    }
    glEnd();
}

//------画对角线
void Cube::renderDiagonal()
{
    drawLine(0,1,2,3);
    drawLine(7,6,5,4);
    drawLine(1,0,4,5);
    drawLine(2,1,5,6);
    drawLine(3,2,6,7);
    drawLine(0,3,7,4);
}

void Cube::drawLine(int v0, int v1, int v2, int v3)
{
    Vec3 pv[4];
    pv[0] = positions_[v0];
    pv[1] = positions_[v1];
    pv[2] = positions_[v2];
    pv[3] = positions_[v3];
    glColor4d(0,0,0,1);
    glBegin(GL_LINES);
    for(int i=0; i < 4; i++)
    {
       glVertex3dv(pv[i].data());
       glVertex3dv(pv[(i+2)%4].data());
    }
    glEnd();
}
}}
